package lv.clientedisqueria.controller;

import java.awt.event.ActionEvent;
import java.util.Observer;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JOptionPane;

import lv.clientedisqueria.model.Modelo;
import lv.clientedisqueria.view.Mensajeria;
import lv.mensajeriadisqueria.idomain.IDomain;

/**
 * 
 * @param <Model>
 */
public class Controller<Entity extends IDomain> {

	private AbstractAction insertar;
	private AbstractAction modificar;
	private AbstractAction borrar;
	private AbstractAction guardar;
	private AbstractAction cancelar;
	
	private final Modelo<Entity> modelo;
	
	public Controller(Modelo<Entity> modelo) {
		this.modelo = modelo;
		estadoInicialAcciones();
	}
	
	@SuppressWarnings("serial")
	public Action getInsertarAction() {
		if (insertar == null) {
			insertar = new AbstractAction("Insertar") {
				@Override
				public void actionPerformed(ActionEvent e) {
					modelo.insertar();
					desHabilitarAcciones();
				}
			};
		}
		return insertar;
	}

	@SuppressWarnings("serial")
	public Action getModificarAction() {
		if (modificar == null) {
			modificar = new AbstractAction("Modificar"){
				@Override
				public void actionPerformed(ActionEvent e) {
					if (esSeleccionado()) {
						modelo.modificar();
						desHabilitarAcciones();
					}
				}
			};
		}
		return modificar;
	}

	@SuppressWarnings("serial")
	public Action getBorrarAction() {
		if (borrar == null) {
			borrar = new AbstractAction("Borrar"){
				@Override
				public void actionPerformed(ActionEvent e) {
					if (esSeleccionado()) {
						Integer mensajePregunta = Mensajeria.mensajePregunta1(e.getSource(), "Borrar", "¿Desea borrar la entidad?");
						if (mensajePregunta == JOptionPane.YES_OPTION) {
							estadoInicialAcciones();
							modelo.borrar();
						}
					} else {
						Mensajeria.mensajeInformacion(e.getSource(), "Borrar", "No existen entidades seleccionados para borrar");
					}
				}
			};
		}
		return borrar; 
	}

	@SuppressWarnings("serial")
	public Action getGuardarAction() {
		if (guardar == null) {
			guardar = new AbstractAction("Guardar"){
				@Override
				public void actionPerformed(ActionEvent e) {
					Integer mensajePregunta = Mensajeria.mensajePregunta2(e.getSource(), "Guardar", "¿Desea Guardar los cambios?");
					if ( mensajePregunta == JOptionPane.YES_OPTION) {
						estadoInicialAcciones();
						modelo.notificar(Modelo.GUARDAR);
					}
				}
			};
		}
		return guardar;
	}
	
	@SuppressWarnings("serial")
	public Action getCancelarAction() {
		if (cancelar == null) {
			cancelar = new AbstractAction("Cancelar"){
				@Override
				public void actionPerformed(ActionEvent e) {
					estadoInicialAcciones();
					modelo.notificar(Modelo.CANCELAR);
				}
			};
		}
		return cancelar; 
	}
	
	/**
	 * 
	 * @return devuelve true o false si hay un objeto seleccionado o no respectivamente.
	 */
	private boolean esSeleccionado() {
		return modelo.getTablaModel().getSeleccionado()!=null;
	}
	
	/**
	 * Es el estado inicial de las acciones
	 */
	protected void estadoInicialAcciones() {
		getInsertarAction().setEnabled(true);
		getModificarAction().setEnabled(true);
		getBorrarAction().setEnabled(esSeleccionado());
		getGuardarAction().setEnabled(false);
		getCancelarAction().setEnabled(false);
	}
	
	protected void desHabilitarAcciones() {
		getInsertarAction().setEnabled(false);
		getModificarAction().setEnabled(false);
		getBorrarAction().setEnabled(false);
		getGuardarAction().setEnabled(true);
		getCancelarAction().setEnabled(true);
	}
	
	/**
	 * Para adherir observer al modelo
	 * @param observer que se va a obsevar
	 */
	public void addObserver(Observer observer) {
		this.modelo.addObserver(observer);
	}

//*************************** ACCIONES DE MODELO *****************************************	
	public void guardar(Entity entity) {
		modelo.guardar(entity);
	}

	public Modelo<Entity> getModelo() {
		return modelo;
	}
}
